package com.example.service.impl;

import com.example.pojo.Book;
import com.example.pojo.BookCSV;
import com.example.pojo.BookTanshu;
import com.example.pojo.ChineseImageLabel;
import com.example.service.BookService;
import com.example.utils.ExcelUtils;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.SocketException;
import java.net.URL;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class BookServiceImpl implements BookService {
    @Override
    public String deduplicateBook(String originalPath) {
        List<Book> bookList = ExcelUtils.readExcel(originalPath, Book.class);
        if(bookList==null){
            return "文件不存在";
        }
        int count=0;
        for (int i = 0; i < bookList.size(); i++) {
            for (int j = i+1; j < bookList.size(); j++) {
                if(equals(bookList.get(i),bookList.get(j))){
                    bookList.remove(j);
                    j--;
                    count++;
                }
            }
        }
        ExcelUtils.writeExcel(originalPath,bookList, Book.class);
        return "成功（去重了"+count+"个）";
    }

    @Override
    public String fillLabelName(String originalPath, String targetPath) {
        List<Book> bookList = ExcelUtils.readExcel(originalPath, Book.class);
        List<ChineseImageLabel> chineseImageLabelList = ExcelUtils.readExcel(targetPath, ChineseImageLabel.class);
        if(bookList==null||chineseImageLabelList==null){
            return "文件不存在";
        }
        Set<ChineseImageLabel> chineseImageLabelSet = new HashSet<>(chineseImageLabelList);
        //按照中图分类前缀填充标签
        int count=0;
        for (Book book : bookList) {
            if(book.getChineseImagePrefix()==null||book.getLabelName()!=null){
                continue;
            }
            for (ChineseImageLabel chineseImageLabel : chineseImageLabelSet) {
                if(chineseImageLabel.getChineseImagePrefix()==null||chineseImageLabel.getLabelName()==null){
                    continue;
                }
                if(book.getChineseImagePrefix().equalsIgnoreCase(chineseImageLabel.getChineseImagePrefix())){
                    book.setLabelName(chineseImageLabel.getLabelName());
                    count++;
                    break;
                }
            }
        }
        ExcelUtils.writeExcel(originalPath,bookList, Book.class);
        return "成功（填充了标签"+count+"个）";
    }

    @Override
    public String mergeCSV(String dirPath) {
        File dirFile = new File(dirPath);
        if(dirFile==null){
            return "目录不存在！";
        }
        int num=0;
        File[] files = dirFile.listFiles();
        List<BookCSV> mergeList=new ArrayList<>();
        for (File file : files) {
            List<BookCSV> bookCSVList = ExcelUtils.readCSV(file, BookCSV.class, 0);
            if(bookCSVList==null){
                System.out.println("文件不出在或异常："+file.getName());
                num++;
                continue;
            }
            mergeList.addAll(bookCSVList);
        }
        ExcelUtils.writeExcel(dirPath+"/合并后.xlsx",mergeList, BookCSV.class);
        return "成功（合并"+(files.length-num)+"个文件）";
    }

    @Override
    public String mergeXlsx(String dirPath) {
        File dirFile = new File(dirPath);
        if(dirFile==null){
            return "目录不存在！";
        }
        int num=0;
        File[] files = dirFile.listFiles();
        List<Book> mergeList=new ArrayList<>();
        for (File file : files) {
            List<Book> bookList = ExcelUtils.readExcel(file.getAbsolutePath(), Book.class);
            if(bookList==null){
                System.out.println("文件不存在或异常："+file.getName());
                num++;
                continue;
            }
            mergeList.addAll(bookList);
        }
        ExcelUtils.writeExcel(dirPath+"/合并后.xlsx",mergeList, Book.class);
        return "成功（合并"+(files.length-num)+"个文件）";
    }

    @Override
    public String checkImageExist(String originalPath){
        List<Book> bookList = ExcelUtils.readExcel(originalPath, Book.class);
        if(bookList==null){
            return "文件不存在";
        }
        int count=0;
        HttpURLConnection httpURLConnection=null;
        for (Book book : bookList) {
            String imageUrl=book.getImg();
            if(imageUrl==null){
                continue;
            }
            try {
                URL url = new URL(imageUrl);
                httpURLConnection= (HttpURLConnection) url.openConnection();
                httpURLConnection.setRequestMethod("HEAD");
                //两者应同时设置以确保在网络问题发生时能够及时响应‌
                httpURLConnection.setConnectTimeout(3000);//建立连接的超时时间为3秒
                httpURLConnection.setReadTimeout(3000);//建立连接后，从服务器读取数据的超时时间为3秒。防止程序长时间等待；在网络不佳时尤为重要
                //HTTP_NOT_MODIFIED(304)：表示客户端发送了一个条件性请求，并且服务器发现自从上次请求以来资源并没有改变，因此返回这个状态码而不是重复传输相同的数据
                if(httpURLConnection.getResponseCode()!=HttpURLConnection.HTTP_OK
                        &&httpURLConnection.getResponseCode()!=HttpURLConnection.HTTP_NOT_MODIFIED){
                    book.setImg(null);
                    count++;
                }
            } catch (SocketException e) {
                System.out.println("抛出SocketException异常："+imageUrl);
            } catch (Exception e){
                System.out.println("抛出其它异常："+imageUrl);
            } finally {
                if(httpURLConnection!=null){
                    httpURLConnection.disconnect();
                }
            }
        }
        ExcelUtils.writeExcel(originalPath,bookList, Book.class);
        return "成功（清除了"+count+"个图片）";
    }

    @Override
    public String addPreservation(String originalPath) {
        List<Book> bookList = ExcelUtils.readExcel(originalPath, Book.class);
        if(bookList==null){
            return "文件不存在";
        }
        for (Book book : bookList) {
            if(book.getPublishTime()==null){
                //出版日期为空，当做00年处理
                Double preservation = caculatePreservation(0.4, book.getPrice());
                if(preservation==null){
                    System.out.println(book.getPrice()+"保值率计算出错");
                    continue;
                }
                book.setPreservation(preservation);
                continue;
            }
            String publishTime = book.getPublishTime().toString();
            if(publishTime.startsWith("198")){
                Double preservation = caculatePreservation(0.5, book.getPrice());
                if(preservation==null){
                    System.out.println(publishTime+"，"+book.getPrice()+"保值率计算出错");
                    continue;
                }
                book.setPreservation(preservation);
            }else if(publishTime.startsWith("199")){
                Double preservation = caculatePreservation(0.45, book.getPrice());
                if(preservation==null){
                    System.out.println(publishTime+"，"+book.getPrice()+"保值率计算出错");
                    continue;
                }
                book.setPreservation(preservation);
            }else if(publishTime.startsWith("200")){
                Double preservation = caculatePreservation(0.4, book.getPrice());
                if(preservation==null){
                    System.out.println(publishTime+"，"+book.getPrice()+"保值率计算出错");
                    continue;
                }
                book.setPreservation(preservation);
            }else if(publishTime.startsWith("201")){
                Double preservation = caculatePreservation(0.35, book.getPrice());
                if(preservation==null){
                    System.out.println(publishTime+"，"+book.getPrice()+"保值率计算出错");
                    continue;
                }
                book.setPreservation(preservation);
            }else if(publishTime.startsWith("202")){
                Double preservation = caculatePreservation(0.3, book.getPrice());
                if(preservation==null){
                    System.out.println(publishTime+"，"+book.getPrice()+"保值率计算出错");
                    continue;
                }
                book.setPreservation(preservation);
            }else if(Integer.parseInt(publishTime.substring(0,3))>=203){
                book.setPreservation(0.5); //2030年以后保值率给0.5
            }else {
                //80年之前保值率给0.7
                book.setPreservation(0.7);
            }
        }
        ExcelUtils.writeExcel(originalPath,bookList, Book.class);
        return "成功";
    }

    @Override
    public String extractCSV(String originalDirPath, String targetDirPath) throws IOException {
        File originalDir = new File(originalDirPath);
        if(originalDir==null){
            return "目录不存在";
        }
        File targetDir = new File(targetDirPath);
        if(!targetDir.exists()){
            targetDir.mkdir();
        }
        File[] files = originalDir.listFiles();
        for (File file : files) {
            if(!file.isDirectory()){
                continue;
            }
            File[] files1 = file.listFiles();
            for (File file1 : files1) {
                if(!file1.isFile()){
                    continue;
                }
                String name = file1.getName();
                if(name.substring(name.lastIndexOf('.')+1).equals("csv")){
                    File targetFile=new File(targetDir,"/"+name);
                    Files.copy(file1.toPath(),targetFile.toPath());
                    break;
                }

            }
        }
        return "成功";
    }

    @Override
    public String deduplicateByIsbnPriceOther(String originalPath) {
        List<Book> bookList = ExcelUtils.readExcel(originalPath, Book.class);
        if(bookList==null){
            return "文件不存在";
        }
        int count=0;
        for (int i = 0; i < bookList.size(); i++) {
            Book book = bookList.get(i);
            if(book.getIsbn()==null||book.getPrice()==null){
                continue;
            }
            for (int j = i+1; j < bookList.size(); j++) {
                Book book1 = bookList.get(j);
                if(book1.getIsbn()==null||book1.getPrice()==null){
                    continue;
                }
                if(!book.getIsbn().equals(book1.getIsbn())||!book.getPrice().equals(book1.getPrice())){
                    continue;
                }
                if(isHaveSame(book,book1)){
                    bookList.remove(j);
                    j--;
                    count++;
                }
            }
        }
        ExcelUtils.writeExcel(originalPath,bookList, Book.class);
        return "成功（去重了"+count+"个）";
    }

    private boolean isHaveSame(Book book,Book book1){
        int k=1;//记录是否删除
        //以下数据有无一致的话，补充数据库数据只要一条就可以，其余的可以删除，减少查询数据库压力
        k=k*((book.getName()==null)^(book1.getName()==null) ? 0:1);
        k=k*((book.getImg()==null)^(book1.getImg()==null) ? 0:1);
        if(k==0){
            return false;
        }
        k=k*((book.getAuthor()==null)^(book1.getAuthor()==null) ? 0:1);
        k=k*((book.getTranslator()==null)^(book1.getTranslator()==null) ? 0:1);
        if(k==0){
            return false;
        }
        k=k*((book.getPublisher()==null)^(book1.getPublisher()==null) ? 0:1);
        k=k*((book.getPublishTime()==null)^(book1.getPublishTime()==null) ? 0:1);
        if(k==0){
            return false;
        }
        k=k*((book.getLabelName()==null)^(book1.getLabelName()==null) ? 0:1);
        k=k*((book.getSummary()==null)^(book1.getSummary()==null) ? 0:1);
        return k==1;
    }

    private Double caculatePreservation(Double beginPreservation,Double price){
        if(beginPreservation==null||price==null){
            return null;
        }
        if(price>=0&&price<=5.5){
            return beginPreservation+0.2;
        }
        if(price>5.5&&price<=7.9){
            return beginPreservation+0.19;
        }
        if(price>7.9&&price<=10){
            return beginPreservation+0.18;
        }
        if(price>10&&price<=12){
            return beginPreservation+0.17;
        }
        if(price>12&&price<=14.8){
            return beginPreservation+0.16;
        }
        if(price>14.8&&price<=16.8){
            return beginPreservation+0.15;
        }
        if(price>16.8&&price<=19){
            return beginPreservation+0.14;
        }
        if(price>19&&price<=21){
            return beginPreservation+0.13;
        }
        if(price>21&&price<=24){
            return beginPreservation+0.12;
        }
        if(price>24&&price<=26){
            return beginPreservation+0.11;
        }
        if(price>26&&price<=28){
            return beginPreservation+0.10;
        }
        if(price>28&&price<=30){
            return beginPreservation+0.09;
        }
        if(price>30&&price<=34){
            return beginPreservation+0.08;
        }
        if(price>34&&price<=37.9){
            return beginPreservation+0.07;
        }
        if(price>37.9&&price<=39.8){
            return beginPreservation+0.06;
        }
        if(price>39.8&&price<=46){
            return beginPreservation+0.05;
        }
        if(price>46&&price<=52){
            return beginPreservation+0.04;
        }
        if(price>52&&price<=65){
            return beginPreservation+0.03;
        }
        if(price>65&&price<=81){
            return beginPreservation+0.02;
        }
        if(price>81&&price<=138){
            return beginPreservation+0.01;
        }
        if(price>138){
            return beginPreservation;
        }
        return null;
    }

    private boolean equals(Book book,Book book2){
        int i=1;
        if(book.getName()!=null&&book2.getName()!=null){
            if(book.getName().equals(book2.getName())){
                i=i*1;
            }else {
                i=i*0;
            }
        }
        i=i*((book.getName()==null)^(book2.getName()==null) ? 0:1);
        if(i==0){
            return false;
        }
        if(book.getImg()!=null&&book2.getImg()!=null){
            if(book.getImg().equals(book2.getImg())){
                i=i*1;
            }else {
                i=i*0;
            }
        }
        i=i*((book.getImg()==null)^(book2.getImg()==null) ? 0:1);
        if(book.getAuthor()!=null&&book2.getAuthor()!=null){
            if(book.getAuthor().equals(book2.getAuthor())){
                i=i*1;
            }else {
                i=i*0;
            }
        }
        i=i*((book.getAuthor()==null)^(book2.getAuthor()==null) ? 0:1);
        if(i==0){
            return false;
        }
        if(book.getEditor()!=null&&book2.getEditor()!=null){
            if(book.getEditor().equals(book2.getEditor())){
                i=i*1;
            }else {
                i=i*0;
            }
        }
        i=i*((book.getEditor()==null)^(book2.getEditor()==null) ? 0:1);
        if(book.getTranslator()!=null&&book2.getTranslator()!=null){
            if(book.getTranslator().equals(book2.getTranslator())){
                i=i*1;
            }else {
                i=i*0;
            }
        }
        i=i*((book.getTranslator()==null)^(book2.getTranslator()==null) ? 0:1);
        if(book.getPublisher()!=null&&book2.getPublisher()!=null){
            if(book.getPublisher().equals(book2.getPublisher())){
                i=i*1;
            }else {
                i=i*0;
            }
        }
        i=i*((book.getPublisher()==null)^(book2.getPublisher()==null) ? 0:1);
        if(book.getPrice()!=null&&book2.getPrice()!=null){
            if(book.getPrice().equals(book2.getPrice())){
                i=i*1;
            }else {
                i=i*0;
            }
        }
        i=i*((book.getPrice()==null)^(book2.getPrice()==null) ? 0:1);
        if(book.getPublishTime()!=null&&book2.getPublishTime()!=null){
            if(book.getPublishTime().equals(book2.getPublishTime())){
                i=i*1;
            }else {
                i=i*0;
            }
        }
        i=i*((book.getPublishTime()==null)^(book2.getPublishTime()==null) ? 0:1);
        if(book.getIsbn()!=null&&book2.getIsbn()!=null){
            if(book.getIsbn().equals(book2.getIsbn())){
                i=i*1;
            }else {
                i=i*0;
            }
        }
        i=i*((book.getIsbn()==null)^(book2.getIsbn()==null) ? 0:1);
        if(book.getChineseImage()!=null&&book2.getChineseImage()!=null){
            if(book.getChineseImage().equalsIgnoreCase(book2.getChineseImage())){
                i=i*1;
            }else {
                i=i*0;
            }
        }
        i=i*((book.getChineseImage()==null)^(book2.getChineseImage()==null) ? 0:1);
        if(book.getSummary()!=null&&book2.getSummary()!=null){
            if(book.getSummary().equals(book2.getSummary())){
                i=i*1;
            }else {
                i=i*0;
            }
        }
        i=i*((book.getSummary()==null)^(book2.getSummary()==null) ? 0:1);
        if(book.getKeyword()!=null&&book2.getKeyword()!=null){
            if(book.getKeyword().equals(book2.getKeyword())){
                i=i*1;
            }else {
                i=i*0;
            }
        }
        i=i*((book.getKeyword()==null)^(book2.getKeyword()==null) ? 0:1);
        return i==1;
    }
}
